import { Injectable, Logger, NotFoundException, BadRequestException } from '@nestjs/common';
import { IsDecimal, IsEnum, IsInt, IsNotEmpty, Min,IsString,IsOptional } from 'class-validator';
import { InjectRepository } from '@nestjs/typeorm';
import { Payment } from '../entity/payment.entity';
import { Repository } from 'typeorm';
import { CreatePaymentDto } from './create-payment.dto';
import { firstValueFrom,RetryConfig } from 'rxjs';
import { intervalBackoff } from 'backoff-rxjs';
import {sampleTime, startWith, switchMap} from 'rxjs/operators';
import { Order } from '../entity/order.entity';
import { User } from '../entity/user.entity';
import { UserDetail } from '../entity/userDetail.entity';
// import { ApiProperty } from '@nestjs/swagger';
import {OrderNumberService} from '../order-number/order-number.service'

import { OrderStatus } from '../entity/order.entity'
import crypto from 'crypto'
import { HttpService } from '@nestjs/axios';
import { FormatService } from '../format/format.service';
import  AlipaySDKconfig from '../config/alipay.config';
import { OrderItem } from '../entity/order-item.entity';
const { AlipaySdk } = require("alipay-sdk");
type AlipaySdk = /*unresolved*/ any
// const fs = require("fs");
// const privateKey = fs.readFileSync("../config/privatekey.pem", "ascii");
// const alipayPublicKey = fs.readFileSync("../config/publickey.pem", "ascii");
export enum PaymentStatus {
    PENDING = 'PENDING',
    COMPLETED = 'COMPLETED',
    FAILED = 'FAILED',
    REFUNDED = 'REFUNDED'
  }

 export enum PaymentMethod {
    ALIPAY = 'ALIPAY',
    WECHAT = 'WECHAT',
    UNIONPAY = 'UNIONPAY',
    BALANCE = 'BALANCE'
}
@Injectable()
export class PaymentService {
  constructor(
    @InjectRepository(Payment)
    private paymentRepository: Repository<Payment>,
    @InjectRepository(Order)
    private orderRepository: Repository<Order>,
    // @InjectRepository(User)
      //   private userRepository: Repository<User>,
    @InjectRepository(UserDetail)
    private readonly userDetailRepository: Repository<UserDetail>,
    private readonly httpService: HttpService,
    private readonly generateOrderNo: OrderNumberService,
    private readonly formatService: FormatService,
    @InjectRepository(OrderItem)
        private orderItemRepository: Repository<OrderItem>,
    // private fromAlipay:Repository<AlipaySdk>,
  ) {}


    alipayResult:any
    async createPayment(orderId: number, userId: number, method: PaymentMethod) {
       console.log('find-order:start')
    const order = await this.orderRepository.findOne({
      where: { id: orderId },
      // relations: ['user_id'],
    });
    console.log('order:',order)
    if (!order) {
      throw new NotFoundException('订单不存?');
    }

    if (order.user_id !== userId) {
      throw new BadRequestException('无权操作此订?');
    }

    if (order.status !== 'PENDING') {
      throw new BadRequestException('订单状态不正确');
    }
    const paymentNo = this.generateOrderNo.generateOrderNumber('PAY');
      console.log('paymentNo---:', paymentNo)
      console.log('paymentOrder---:', order)
      console.log('method---:', method)
      console.log('PENDING---:', PaymentStatus.PENDING)
      console.log('totalAmount---:', order.totalAmount)
     const date = this.formatService.dateFormate(new Date(),'YYYY-MM-DD HH:mm:ss.SSSSSS')
    const payment = await this.paymentRepository.create({
      paymentNo:paymentNo,
      order,
      orderId:order.id,
      userId:userId ,
      paymentMethod: method,
      amount: order.totalAmount,
      status: PaymentStatus.PENDING,
      paidAt:date,
      updatedAt:date,
      createdAt:date,
    });

    await this.paymentRepository.save(payment);
     console.log('totalAmount---:save:',payment)
    // 根据支付方式处理支付
    switch (method) {
      case PaymentMethod.ALIPAY:
        return this.handleAlipayPayment(payment);
      case PaymentMethod.WECHAT:
        return this.handleWechatPayment(payment);
       case PaymentMethod.UNIONPAY:
        return this.handleUnionPayPayment(payment);
      case PaymentMethod.BALANCE:
        return this.handleBalancePayment(payment);
      default:
        throw new BadRequestException('不支持的支付方式');
    }
  }

  async handleAlipayPayment(payment: Payment) {
    // TODO: 实现支付宝支付逻辑
    console.log('AlipaySDKconfig:start', AlipaySDKconfig.appId)
    console.log('AlipaySDKconfig:start1', AlipaySDKconfig.merchantPrivateKey)
    console.log('AlipaySDKconfig:start2', AlipaySDKconfig.alipayPublicKey)

      try {
         const alipaySdk =new  AlipaySdk({
          appId: AlipaySDKconfig.appId,
          privateKey: AlipaySDKconfig.merchantPrivateKey,
          alipayPublicKey: AlipaySDKconfig.alipayPublicKey,
          gateway: "https://openapi-sandbox.dl.alipaydev.com/gateway.do",
          sandbox: true,
         })
         const order = await this.orderRepository.findOne({
          where: { id: payment.orderId },
          // relations: ['user_id'] ,
         })

         const orderItem = await this.getOrderItemsWithProducts(payment.orderId)
         console.log('输出orderItem：',orderItem)


        //  const productSku = await this.orderItemRepository.findOne({
        //   where: { id: payment.orderId },
        //   relations: ['skuId'] ,
        //  })
        let productList = [];
        for  (const element of orderItem) {
          productList.push({
             productId:element.productSnapshot.id,
             productName:element.productSnapshot.name,
             description:element.productSnapshot.description,
           })
        }


        console.log('输出：',orderItem)


         console.log('productList:',productList)
              const result = alipaySdk.pageExec("alipay.trade.page.pay", {
                  bizContent: {
                  out_trade_no:order.orderNo,
                  total_amount: payment.amount,
                  subject: productList[0].productName,
                  body: productList[0].description, // 订单描述
                  // subject:order.title,
                  // product_code:payment.paymentNo,
                  product_code: "FAST_INSTANT_TRADE_PAY",
                  timeout_express: "30m",
                  returnUrl:'http://localhost:1988/api/payments/notify/alipay'
                },
              });
              console.log('阿里沙箱支付：', result)

               this.alipayResult = result
               return {
                result,
                paymentId: payment.id,
                paymentNo: payment.paymentNo,
                amount: payment.amount,
                payUrl: 'http://localhost:1988/api/payments/alipay/index', // 示例支付链接
              };
      } catch (error) {
           console.log('AlipaySDKconfig:err',error)
      }

    // 2. 返回支付链接或二维码


  }

  async getOrderItemsWithProducts(orderId: number) {
    return this.orderItemRepository
      .createQueryBuilder('orderItem')
      //
      .leftJoinAndSelect('orderItem.sku', 'productSku')
      // .leftJoinAndSelect('orderItem.product', 'product')
      .where('orderItem.orderId = :orderId', { orderId })
      .getMany();
  }
  getAliPayFrom() {
    return this.alipayResult
  }

  async handleWechatPayment(payment: Payment) {
    // TODO: 实现微信支付逻辑
    // 1. 调用微信支付SDK创建支付订单
    // 2. 返回支付二维
    return {
      paymentId: payment.id,
      paymentNo: payment.paymentNo,
      amount: payment.amount,
      qrCode: 'https://example.com/wechat/qrcode', // 示例二维码链
    };
  }

  handleUnionPayPayment(payment) {
    return {
      paymentId: payment.id,
      paymentNo: payment.paymentNo,
      amount: payment.amount,
    }
  }

  async handleBalancePayment(payment: Payment) {
    const user = await this.userDetailRepository.findOne({
      where: { user_id: payment.userId },
    });

    if (!user) {
      throw new NotFoundException('用户不存?');
    }

    if (user.balance < payment.amount) {
      throw new BadRequestException('余额不足');
    }

    // 扣除用户余额
    user.balance -= payment.amount;
    await this.userDetailRepository.save(user);

    // 更新支付状
    payment.status = PaymentStatus.COMPLETED;
    payment.paidAt = new Date();
    await this.paymentRepository.save(payment);

    // 更新订单状
    const order = payment.order;
    order.status = OrderStatus.PAID;
    await this.orderRepository.save(order);

    return {
      paymentId: payment.id,
      paymentNo: payment.paymentNo,
      amount: payment.amount,
      status: payment.status,
    };
  }

  async queryPayment(paymentId: number) {
    const payment = await this.paymentRepository.findOne({
      where: { id: paymentId },
      // relations: ['order'],
    });

    if (!payment) {
      throw new NotFoundException('支付记录不存?');
    }

    return payment;
  }

  async refundPayment(paymentId: number) {
    const payment = await this.queryPayment(paymentId);
    console.log('refundPayment:',payment)
    if (payment.status !== PaymentStatus.COMPLETED) {
      throw new BadRequestException('支付状态不正确');
    }

    // TODO: 实现退款逻辑
    // 1. 调用支付平台退款接�?
    // 2. 更新支付状�?
    // 3. 更新订单状�?
    // 4. 如果是余额支付，返还用户余额

    payment.status = PaymentStatus.REFUNDED;
    await this.paymentRepository.save(payment);

    return payment;
  }


  async verifyPaymentStatus(paymentId: number) {
    const payment = await this.paymentRepository.findOne({
      where: { id:paymentId },
      relations: ['order']
    });

    if (!payment) {
      throw new Error('支付记录不存?');
    }

    try {
      const response = await firstValueFrom(
        this.httpService
          .get(`https://api.payment-gateway.com/transactions/${payment.transactionId}`)
              .pipe(

            sampleTime(1000),
​
             // Start immediately
              startWith(null),
              switchMap(() => intervalBackoff(1000)),
             //switchMap(() => service.getData()),

          )
      );

    //  const response = 200

      if (response===200) {
        payment.status = PaymentStatus.COMPLETED;
        await this.paymentRepository.save(payment);
      }
      return payment;
    } catch (error) {
      Logger.error(`支付验证失败${error?.message??''}`);
      throw new Error('支付状态验证失?');
    }
  }

  async handleCallback(callbackData: any) {
    // 验证签名
    const isValid = this.validateSignature(callbackData);
    if (!isValid) {
      throw new Error('非法回调请求');
    }

    const payment = await this.paymentRepository.findOne({
      where: { transactionId: callbackData.transaction_id }
    });

    if (payment) {
      payment.status = callbackData.status === 'success' ? PaymentStatus.COMPLETED :PaymentStatus.FAILED;
      payment.updatedAt = new Date();
      await this.paymentRepository.save(payment);

      // 触发订单状态更
      if (payment.status === PaymentStatus.COMPLETED) {
        await this.updateOrderStatus(payment.orderId,  OrderStatus.PAID);
      }
    }
  }

  private async callPaymentGateway() {
    const config = {
      headers: {
        'Authorization': `Bearer ${process.env.PAYMENT_API_KEY}`,
        'Content-Type': 'application/json'
      }
    };

    const response = await firstValueFrom(
      this.httpService.post(
        'https://api.payment-gateway.com/transactions',
        { /* 支付请求参数 */ },
        config
      )
    );

    return response.data;
  }

  private validateSignature(data: any): boolean {
    const sign = data.sign;
    const payload = JSON.stringify({
      transaction_id: data.transaction_id,
      amount: data.amount,
      timestamp: data.timestamp
    });

    const expectedSign = crypto
      .createHmac('sha256', process.env.PAYMENT_SECRET)
      .update(payload)
      .digest('hex');

    return sign === expectedSign;
  }

  private async updateOrderStatus(orderId: number, status: string) {
    try {
      await this.httpService.patch(
        `http://order-service/orders/${orderId}/status`,
        { status },
        { headers: { 'x-service-token': process.env.INTERNAL_API_KEY } }
      );
    } catch (error) {
      Logger.error(`订单状态更新失败：${error.message}`);
      throw new Error('订单状态同步异?');
    }
  }

  // @ApiProperty({
  //   description: '支付金额',
  //   example: 100.50,
  //   minimum: 0.01,
  //   maximum: 1000000
  // })
  // @IsDecimal({ decimal_digits: '2' })
  // @Min(0.01)
  // amount: number;

  private validateStatusTransition(currentStatus: PaymentStatus, newStatus: PaymentStatus) {
    const allowedTransitions = {
      [PaymentStatus.PENDING]: [PaymentStatus.COMPLETED, PaymentStatus.FAILED],
      [PaymentStatus.COMPLETED]: [PaymentStatus.REFUNDED],
      [PaymentStatus.FAILED]: [PaymentStatus.PENDING],
      [PaymentStatus.REFUNDED]: []
    };

    if (!allowedTransitions[currentStatus].includes(newStatus)) {
      throw new Error(`无效状态转换：${currentStatus} -> ${newStatus}`);
    }
  }

  async updatePaymentStatus(paymentId: number, newStatus: PaymentStatus) {
    const payment = await this.paymentRepository.findOne({ where: { id: paymentId } });
    this.validateStatusTransition(payment.status, newStatus);
    payment.status = newStatus;
    return this.paymentRepository.save(payment);
  }
}

